package com.heima.minio.service.impl;

import com.heima.minio.config.ClientConfig;
import com.heima.minio.config.MinioConfigParam;
import com.heima.minio.service.FileUploadServer;
import io.minio.*;
import io.minio.errors.*;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Import;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 对外提供minio的文件管理功能(上传、下载、删除)
 */
@EnableConfigurationProperties(MinioConfigParam.class)
@Import(ClientConfig.class)
public class FileUploadServerImpl implements FileUploadServer {

    @Autowired
    private MinioConfigParam configParam;

    @Autowired
    private MinioClient client;

    private String genFileDatePath(String fileName){
        String formatPath = new SimpleDateFormat("yyyy/MM/dd/").format(new Date()) + fileName;
        return formatPath;
    }
    /**
     * 文件上传
     *  要素：桶名字（可配置）、文件路径(年/月/日/)、文件名(传过来)、文件输入流(传过来)
     */
    //TODO 优化传参参数
    public String uploadFile(String fileName, String contentType, InputStream is){
        //1.得到client
//        MinioClient client = getClient();

        //2.判断桶是否存在并创建
        //TODO 优化2
        String bucketName = configParam.getBucketName();
        try {
            boolean exists = client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if(!exists){
                client.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
            //3.构建文件目录，上传到桶
            String filePath = genFileDatePath(fileName);
            client.putObject(PutObjectArgs.builder()
                            .bucket(bucketName)
                            .contentType(contentType)
                            .object(filePath)
                            .stream(is,is.available(),-1)
                    .build());
            //4.返回文件访问路径
            //TODO 优化拼接参数
            String redirectPath = configParam.getEndpoint() + "/"+bucketName+"/"+filePath;
            return redirectPath;

        } catch (Exception e) {

            throw new RuntimeException(e);
        }

    }
    /**
     * 文件下载
     * leadnews/2023/xx/111/1.jpg
     */
    public InputStream downloadFile(String redirectPath){
        InputStream inputStream = null;
        //1.得到client
//        MinioClient client = getClient();
        //2.下载
        //2.1 处理桶 和 文件名
        String bucketObjectPath = redirectPath.replace(configParam.getEndpoint()+"/", "");

        int index = bucketObjectPath.indexOf("/");

        String bucketName = bucketObjectPath.substring(0, index);
        String fileName = bucketObjectPath.substring(index+1);
        try {
            inputStream = client.getObject(GetObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .build());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return inputStream;
    }

    @Override
    public byte[] downloadFileWithByte(String redirectPath) {
        InputStream inputStream = this.downloadFile(redirectPath);
        try {
            byte[] bytes = IOUtils.toByteArray(inputStream);
            return bytes;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 文件删除
     */
    public void remove(String redirectPath){
        //1.得到client
//        MinioClient client = getClient();
        //
        //2.1 处理桶 和 文件名
        String bucketObjectPath = redirectPath.replace(configParam.getEndpoint(), "");

        int index = bucketObjectPath.indexOf("/");

        String bucketName = bucketObjectPath.substring(0, index);
        String fileName = bucketObjectPath.substring(index+1);
        try {
            client.removeObject(RemoveObjectArgs.builder()
                    .bucket(bucketName).object(fileName).build());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
